package com.example.grpc.openapi.client.create;

import com.example.grpc.openapi.CreateOpenAPI;
import com.example.grpc.openapi.client.GrpcClient;
import com.example.grpc.openapi.request.CreateRequest;
import com.example.grpc.openapi.response.ResponseResult;
import com.google.protobuf.BoolValue;
import com.google.protobuf.InvalidProtocolBufferException;
import com.openapi.proto.CreateOpenAPIGrpc;
import com.openapi.proto.CreateOpenAPIProto;
import io.grpc.ManagedChannel;
import io.grpc.StatusRuntimeException;

public class CreateOpenAPIGrpcClient extends GrpcClient implements CreateOpenAPI {

    private static volatile CreateOpenAPIGrpcClient INSTANCE;

    private CreateOpenAPIGrpcClient(String target, long timeout) {
        super(target, timeout);
    }

    public static CreateOpenAPIGrpcClient getInstance(String target, long timeout) {
        if (INSTANCE == null) {
            synchronized (CreateOpenAPIGrpcClient.class) {
                if (INSTANCE == null) {
                    INSTANCE = new CreateOpenAPIGrpcClient(target, timeout);
                }
            }
        }
        return INSTANCE;
    }

    @Override
    public ResponseResult<Boolean> create(CreateRequest request) {
        if (request == null) {
            return ResponseResult.fail("A01", "请求参数缺失", null);
        }

        CreateOpenAPIGrpc.CreateOpenAPIBlockingStub blockingStub = null;
        try {
            // 构建Request
            CreateOpenAPIProto.CreateRequest rcpRequest = buildRequest(request);
            // 构建RpcStub
            blockingStub = buildStub();

            // 发起调用
            CreateOpenAPIProto.RpcResponseResult rpcResponse = blockingStub.create(rcpRequest);

            // 包装Response
            return toBooleanResponse(rpcResponse);
        } catch (Exception e) {
            return handleException(e);
        } finally {
            if (blockingStub != null) {
                shutdownChannel((ManagedChannel) blockingStub.getChannel());
            }
        }
    }


    private CreateOpenAPIProto.CreateRequest buildRequest(CreateRequest request) {
        CreateOpenAPIProto.CreateRequest.Builder builder =
                CreateOpenAPIProto.CreateRequest.newBuilder();
        if (request.getName() != null) {
            builder.setName(request.getName() + "-" + request.getComment());
        }

        return builder.build();
    }


    private CreateOpenAPIGrpc.CreateOpenAPIBlockingStub buildStub() {
        return CreateOpenAPIGrpc.newBlockingStub(getChannel())
                .withDeadlineAfter(getTimeout(), DEFAULT_TIMEOUT_UNIT);
    }

    private ResponseResult<Boolean> toBooleanResponse(CreateOpenAPIProto.RpcResponseResult rpcResponse)
            throws InvalidProtocolBufferException {
        if (ResponseResult.SUCCESS_CODE.equals(rpcResponse.getCode())) {
            // 使用 RpcResponseResult的hasData方法判断any对象是否为null,为null则根据业务逻辑自行处理
            if (!rpcResponse.hasData()) {
                return ResponseResult.success();
            }

            // 若不为null，则使用RpcResponseResult的getData()方法获取any对象
            // 获取到any对象后，使用any.unpack(Class<T> clazz);方法进行反序列化,获取到真正的Response模型对象
            BoolValue result = rpcResponse.getData().unpack(BoolValue.class);
            return ResponseResult.success(result.getValue());
        } else {
            return ResponseResult.fail(rpcResponse.getCode(), rpcResponse.getMsg(), rpcResponse.getSubMsg());
        }
    }


    private <T> ResponseResult<T> handleException(Exception e) {
        if (e instanceof StatusRuntimeException) {
            e.printStackTrace();
            return ResponseResult.fail("E01", e.getMessage());
        } else {
            e.printStackTrace();
            return ResponseResult.fail("E01", "系统执行错误", e.getMessage());
        }
    }

}
